package com.studynotes.dev.tech.common.utils;

import cn.hutool.core.lang.func.Func0;
import cn.hutool.core.lang.func.Func1;
import cn.hutool.core.lang.func.VoidFunc0;
import cn.hutool.core.lang.func.VoidFunc1;
import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.ObjectUtil;
import lombok.SneakyThrows;

import java.util.Optional;
import java.util.function.*;

/**
 * @author Liu XiaoJun
 * @description: Optional工具类，处理空值场景
 * @date 2025-11-07 12:26:38
 */
public class OptionalUtil {

    private OptionalUtil() {

    }

    /**
     * 获取默认值
     *
     * @param value 要获取的值
     * @param supplier 默认值提供者
     * @param <T> 值类型
     * @return 值
     */
    public static <T> T getDefault(T value, Supplier<T> supplier) {
        return Optional.ofNullable(value).orElseGet(supplier);
    }

    /**
     * 获取默认值
     *
     * @param value 要获取的值
     * @param defaultValue 默认值
     * @param <T> 值类型
     * @return 值
     */
    public static <T> T getDefault(T value, T defaultValue) {
        return Optional.ofNullable(value).orElse(defaultValue);
    }

    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     * @param param 参数
     * @param <P> 参数类型
     * @param <R> 返回值类型
     * @return 返回值
     */
    public static <P, R> R ofBoolean(boolean value, Function<P, R> trueFunc, Function<P, R> falseFunc, P param) {
        if (value) {
            return trueFunc.apply(param);
        }
        return falseFunc.apply(param);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param value 判断的值
     * @param trueFunc 执行的方法
     * @param param 参数
     * @param <P> 参数类型
     * @param <R> 返回值类型
     * @return 返回值
     */
    public static <P, R> R isTrue(boolean value, Function<P, R> trueFunc, P param) {
        return ofBoolean(value, trueFunc, p -> null, param);
    }


    /**
     * 当值为false时执行方法，并返回结果
     *
     * @param value 判断的值
     * @param falseFunc 执行的方法
     * @param param 参数
     * @param <P> 参数类型
     * @param <R> 返回值类型
     * @return 返回值
     */
    public static <P, R> R isFalse(boolean value, Function<P, R> falseFunc, P param) {
        return ofBoolean(value, p -> null, falseFunc, param);
    }

    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     */
    @SneakyThrows
    public static void ofBoolean(boolean value, VoidFunc0 trueFunc, VoidFunc0 falseFunc) {
        if (value) {
            trueFunc.call();
        } else {
            falseFunc.call();
        }
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param value 判断的值
     * @param trueFunc 执行的方法
     */
    @SneakyThrows
    public static void isTrue(boolean value, VoidFunc0 trueFunc) {
        ofBoolean(value, trueFunc, () -> {});
    }


    /**
     * 当值为false时执行方法，并返回结果
     *
     * @param value 判断的值
     * @param falseFunc 执行的方法
     */
    @SneakyThrows
    public static void isFalse(boolean value, VoidFunc0 falseFunc) {
        ofBoolean(value, () -> {}, falseFunc);
    }

    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param <T> 值类型
     * @param <P> 参数类型
     * @param <R> 返回值类型
     * @param predicate 判断的方法
     * @param value 值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     * @param param 参数
     * @return 返回值
     */
    public static <T, P, R> R ofBoolean(Predicate<T> predicate, T value, Function<P, R> trueFunc, Function<P, R> falseFunc, P param) {
        return ofBoolean(predicate.test(value), trueFunc, falseFunc, param);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param <T> 值类型
     * @param <P> 参数类型
     * @param <R> 返回值类型
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 执行的方法
     * @param param 参数
     * @return 返回值
     */
    public static <T, P, R> R isTrue(Predicate<T> predicate, T value, Function<P, R> trueFunc, P param) {
        return isTrue(predicate.test(value), trueFunc, param);
    }


    /**
     * 当值为false时执行方法，并返回结果
     *
     * @param <T> 值类型
     * @param <P> 参数类型
     * @param <R> 返回值类型
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param falseFunc 执行的方法
     * @param param 参数
     * @return 返回值
     */
    public static <T, P, R> R isFalse(Predicate<T> predicate, T value, Function<P, R> falseFunc, P param) {
        return isFalse(predicate.test(value), falseFunc, param);
    }


    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param <T> 值类型
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     */
    @SneakyThrows
    public static <T>  void ofBoolean(Predicate<T> predicate, T value, VoidFunc0 trueFunc, VoidFunc0 falseFunc) {
        ofBoolean(predicate.test(value), trueFunc, falseFunc);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param <T> 值类型
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 执行的方法
     */
    @SneakyThrows
    public static <T> void isTrue(Predicate<T> predicate, T value, VoidFunc0 trueFunc) {
        isTrue(predicate.test(value), trueFunc);
    }


    /**
     * 当值为false时执行方法，并返回结果
     *
     * @param <T> 值类型
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param falseFunc 执行的方法
     */
    @SneakyThrows
    public static <T>  void isFalse(Predicate<T> predicate, T value, VoidFunc0 falseFunc) {
        isFalse(predicate.test(value), falseFunc);
    }



    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param predicate 判断的方法
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     */
    @SneakyThrows
    public static void ofBoolean(BooleanSupplier predicate, VoidFunc0 trueFunc, VoidFunc0 falseFunc) {
        ofBoolean(predicate.getAsBoolean(), trueFunc, falseFunc);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param predicate 判断的方法
     * @param trueFunc 执行的方法
     */
    @SneakyThrows
    public static void isTrue(BooleanSupplier predicate, VoidFunc0 trueFunc) {
        isTrue(predicate.getAsBoolean(), trueFunc);
    }

    /**
     * 当值为false时执行方法，并返回结果
     *
     * @param predicate 判断的方法
     * @param falseFunc 执行的方法
     */
    @SneakyThrows
    public static void isFalse(BooleanSupplier predicate, VoidFunc0 falseFunc) {
        isFalse(predicate.getAsBoolean(), falseFunc);
    }

    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     * @param <R> 返回值的类型
     * @return 返回值
     */
    public static <R> R ofBooleanForResult(boolean value, Supplier<R> trueFunc, Supplier<R> falseFunc) {
        if (value) {
            return trueFunc.get();
        }
        return falseFunc.get();
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param value 判断的值
     * @param trueFunc 执行的方法
     * @param <R> 返回值的类型
     * @return 返回值
     */
    public static <R> R isTrueForResult(boolean value, Supplier<R> trueFunc) {
        return ofBooleanForResult(value, trueFunc, () -> null);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param value 判断的值
     * @param falseFunc 执行的方法
     * @param <R> 返回值的类型
     * @return 返回值
     */
    public static <R> R isFalseForResult(boolean value, Supplier<R> falseFunc) {
        return ofBooleanForResult(value, () -> null, falseFunc);
    }

    /**
     * 根据值执行不同的方法，并返回结果
     *
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     * @param <T> 值类型
     * @param <R> 返回值的类型
     * @return 返回值
     */
    @SuppressWarnings("unused")
    public static <T, R> R ofBooleanForResult(Predicate<T> predicate, T value, Supplier<R> trueFunc, Supplier<R> falseFunc) {
        return ofBooleanForResult(predicate.test(value), trueFunc, falseFunc);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 执行的方法
     * @param <T> 值类型
     * @param <R> 返回值的类型
     * @return 返回值
     */
    @SuppressWarnings("unused")
    public static <T, R> R isTrueForResult(Predicate<T> predicate, T value, Supplier<R> trueFunc) {
        return isTrueForResult(predicate.test(value), trueFunc);
    }

    /**
     * 当值为true时执行方法，并返回结果
     *
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param falseFunc 执行的方法
     * @param <T> 值类型
     * @param <R> 返回值的类型
     * @return 返回值
     */
    @SuppressWarnings("unused")
    public static <T, R> R isFalseForResult(Predicate<T> predicate, T value, Supplier<R> falseFunc) {
        return isFalseForResult(predicate.test(value), falseFunc);
    }

    /**
     * 根据值执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     * @param param 参数
     * @param <P> 参数类型
     */
    public static <P> void ofBooleanWithParam(boolean value, Consumer<P> trueFunc, Consumer<P> falseFunc, P param) {
        if (value) {
            trueFunc.accept(param);
        } else {
            falseFunc.accept(param);
        }
    }

    /**
     * 当值为true时执行方法
     *
     * @param value 判断的值
     * @param trueFunc 执行的方法
     * @param param 参数
     * @param <P> 参数类型
     */
    public static <P> void isTrueWithParam(boolean value, Consumer<P> trueFunc, P param) {
        ofBooleanWithParam(value, trueFunc, p -> {}, param);
    }

    /**
     * 当值为false时执行方法
     *
     * @param value 判断的值
     * @param falseFunc 执行的方法
     * @param param 参数
     * @param <P> 参数类型
     */
    public static <P> void isFalseWithParam(boolean value, Consumer<P> falseFunc, P param) {
        ofBooleanWithParam(value, p -> {}, falseFunc, param);
    }


    /**
     * 根据值执行不同的方法
     *
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 值为true时执行的方法
     * @param falseFunc 值为false执行的方法
     * @param param 参数
     * @param <T> 参数类型
     * @param <P> 参数类型
     */
    @SuppressWarnings("unused")
    public static <T, P> void ofBooleanWithParam(Predicate<T> predicate, T value, Consumer<P> trueFunc, Consumer<P> falseFunc, P param) {
        ofBooleanWithParam(predicate.test(value), trueFunc, falseFunc, param);
    }

    /**
     * 当值为true时执行方法
     *
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param trueFunc 执行的方法
     * @param param 参数
     * @param <T> 值类型
     * @param <P> 参数类型
     */
    public static <T, P> void isTrueWithParam(Predicate<T> predicate, T value, Consumer<P> trueFunc, P param) {
        isTrueWithParam(predicate.test(value), trueFunc, param);
    }

    /**
     * 当值为false时执行方法
     *
     * @param predicate 判断的方法
     * @param value 判断的值
     * @param falseFunc 执行的方法
     * @param param 参数
     * @param <T> 值类型
     * @param <P> 参数类型
     */
    @SuppressWarnings("unused")
    public static <T, P> void isFalseWithParam(Predicate<T> predicate, T value, Consumer<P> falseFunc, P param) {
        isFalseWithParam(predicate.test(value), falseFunc, param);
    }

    /**
     * 判断值是否为null，执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 为null是执行的方法
     * @param falseFunc 不为null是执行的方法
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    @SneakyThrows
    public static <R, T> R ofNull(T value, Func0<R> trueFunc, Func0<R> falseFunc) {
        if (ObjectUtil.isNull(value)) {
            return trueFunc.call();
        }
        return falseFunc.call();
    }

    /**
     * 判断值是否为null，执行不同的方法
     *
     * @param value 判断的值
     * @param param 参数
     * @param trueFunc 为null是执行的方法
     * @param falseFunc 不为null是执行的方法
     * @param <P> 参数类型
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    @SneakyThrows
    public static <P, R, T> R ofNull(T value, P param, Func1<P, R> trueFunc, Func1<P, R> falseFunc) {
        if (ObjectUtil.isNull(value)) {
            return trueFunc.call(param);
        }
        return falseFunc.call(param);
    }

    /**
     * 判断值是否为blank，执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 为null是执行的方法
     * @param falseFunc 不为null是执行的方法
     * @param <R> 返回结果的类型
     * @return 返回结果
     */
    @SneakyThrows
    public static <R> R ofBlank(String value, Func0<R> trueFunc, Func0<R> falseFunc) {
        if (CharSequenceUtil.isBlank(value)) {
            return trueFunc.call();
        }
        return falseFunc.call();
    }

    /**
     * 判断值是否为blank，执行不同的方法
     *
     * @param value 判断的值
     * @param param 参数
     * @param trueFunc 为null是执行的方法
     * @param falseFunc 不为null是执行的方法
     * @param <P> 参数类型
     * @param <R> 返回结果的类型
     * @return 返回结果
     */
    @SneakyThrows
    public static <P, R> R ofBlank(String value, P param, Func1<P, R> trueFunc, Func1<P, R> falseFunc) {
        if (ObjectUtil.isEmpty(value)) {
            return trueFunc.call(param);
        }
        return falseFunc.call(param);
    }

    /**
     * 判断值是否为empty，执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 为null是执行的方法
     * @param falseFunc 不为null是执行的方法
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    @SneakyThrows
    public static <R, T> R ofEmpty(T value, Func0<R> trueFunc, Func0<R> falseFunc) {
        if (ObjectUtil.isEmpty(value)) {
            return trueFunc.call();
        }
        return falseFunc.call();
    }

    /**
     * 判断值是否为empty，执行不同的方法
     *
     * @param value 判断的值
     * @param param 参数
     * @param trueFunc 为null是执行的方法
     * @param falseFunc 不为null是执行的方法
     * @param <P> 参数类型
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    @SneakyThrows
    public static <P, R, T> R ofEmpty(T value, P param, Func1<P, R> trueFunc, Func1<P, R> falseFunc) {
        if (ObjectUtil.isEmpty(value)) {
            return trueFunc.call(param);
        }
        return falseFunc.call(param);
    }

    /**
     * 判断值为null时执行方法
     *
     * @param value 待判断的值
     * @param func 待执行的方法
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    public static <R, T> R isNull(T value, Func0<R> func) {
        return ofNull(value, func, () -> null);
    }

    /**
     * 判断值为null时执行方法
     *
     * @param value 待判断的值
     * @param param 参数
     * @param func 待执行的方法
     * @param <P> 参数类型
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    public static <P, R, T> R isNull(T value, P param, Func1<P, R> func) {
        return ofNull(value, param, func, p -> null);
    }

    /**
     * 判断值不为null时执行方法
     *
     * @param value 待判断的值
     * @param func 待执行的方法
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    @SuppressWarnings("unused")
    public static <R, T> R isNotNull(T value, Func0<R> func) {
        return ofNull(value, () -> null, func);
    }

    /**
     * 判断值不为null时执行方法
     *
     * @param value 待判断的值
     * @param func 待执行的方法
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    public static <R, T> R isNotNull(T value, Func1<T, R> func) {
        return ofNull(value, value, p -> null, func);
    }

    /**
     * 判断值不为null时执行方法
     *
     * @param value 待判断的值
     * @param param 参数
     * @param func 待执行的方法
     * @param <P> 参数类型
     * @param <R> 返回结果的类型
     * @param <T> 值类型
     * @return 返回结果
     */
    @SuppressWarnings("unused")
    public static <P, R, T> R isNotNull(T value, P param, Func1<P, R> func) {
        return ofNull(value, param, p -> null, func);
    }

    /**
     * 判断值是否为null，执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 为null时执行的方法
     * @param falseFunc 不为null时执行的方法
     * @param <T> 值类型
     */
    @SneakyThrows
    public static <T> void ofNullWithout(T value, VoidFunc0 trueFunc, VoidFunc0 falseFunc) {
        if (ObjectUtil.isNull(value)) {
            trueFunc.call();
        } else {
            falseFunc.call();
        }
    }

    /**
     * 判断值是否为empty，执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 为null时执行的方法
     * @param falseFunc 不为null时执行的方法
     * @param <T> 值类型
     */
    @SneakyThrows
    public static <T> void ofEmptyWithout(T value, VoidFunc0 trueFunc, VoidFunc0 falseFunc) {
        if (ObjectUtil.isEmpty(value)) {
            trueFunc.call();
        } else {
            falseFunc.call();
        }
    }

    /**
     * 判断值是否为blank(，执行不同的方法
     *
     * @param value 判断的值
     * @param trueFunc 为null时执行的方法
     * @param falseFunc 不为null时执行的方法
     */
    @SneakyThrows
    public static void ofBlankWithout(String value, VoidFunc0 trueFunc, VoidFunc0 falseFunc) {
        if (CharSequenceUtil.isBlank(value)) {
            trueFunc.call();
        } else {
            falseFunc.call();
        }
    }

    /**
     * 判断值为null时执行方法
     *
     * @param value 待判断的值
     * @param func 待执行的方法
     * @param <T> 值类型
     */
    @SuppressWarnings("unused")
    public static <T> void isNullWithout(T value, VoidFunc0 func) {
        ofNullWithout(value, func, () -> {});
    }

    /**
     * 判断值不为null时执行方法
     *
     * @param value 待判断的值
     * @param func 待执行的方法
     * @param <T> 值类型
     */
    public static <T> void isNotNullWithout(T value, VoidFunc1<T> func) {
        if (ObjectUtil.isNotNull(value)) {
            func.callWithRuntimeException(value);
        }
    }

    /**
     * 判断值不为null时执行方法
     *
     * @param value 待判断的值
     * @param func 待执行的方法
     * @param <T> 值类型
     */
    public static <T> void isNotNullWithout(T value, VoidFunc0 func) {
        ofNullWithout(value, () -> {}, func);
    }


    /**
     * 判断值是否为null，执行不同的方法
     *
     * @param value 判断的值
     * @param param 参数
     * @param trueFunc 为null时执行的方法
     * @param falseFunc 不为null时执行的方法
     * @param <T> 值类型
     * @param <P> 参数类型
     */
    @SneakyThrows
    public static <T, P> void ofNullWithParam(T value, P param, Consumer<P> trueFunc, Consumer<P> falseFunc) {
        if (ObjectUtil.isNull(value)) {
            trueFunc.accept(param);
        } else {
            falseFunc.accept(param);
        }
    }

    /**
     * 判断值是否为empty，执行不同的方法
     *
     * @param value 判断的值
     * @param param 参数
     * @param trueFunc 为null时执行的方法
     * @param falseFunc 不为null时执行的方法
     * @param <T> 值类型
     * @param <P> 参数类型
     */
    @SneakyThrows
    public static <T, P> void ofEmptyWithParam(T value, P param, Consumer<P> trueFunc, Consumer<P> falseFunc) {
        if (ObjectUtil.isEmpty(value)) {
            trueFunc.accept(param);
        } else {
            falseFunc.accept(param);
        }
    }

    /**
     * 判断值是否为blank，执行不同的方法
     *
     * @param value 判断的值
     * @param param 参数
     * @param trueFunc 为null时执行的方法
     * @param falseFunc 不为null时执行的方法
     * @param <P> 参数类型
     */
    @SneakyThrows
    public static <P> void ofBlankWithParam(String value, P param, Consumer<P> trueFunc, Consumer<P> falseFunc) {
        if (CharSequenceUtil.isBlank(value)) {
            trueFunc.accept(param);
        } else {
            falseFunc.accept(param);
        }
    }

    /**
     * 判断值为null时执行方法
     *
     * @param value 待判断的值
     * @param param 参数
     * @param func 待执行的方法
     * @param <T> 值类型
     * @param <P> 参数类型
     */
    @SuppressWarnings("unused")
    public static <T, P> void isNullWithParam(T value, P param, Consumer<P> func) {
        ofNullWithParam(value, param, func, p -> {});
    }

    /**
     * 判断值不为null时执行方法
     *
     * @param value 待判断的值
     * @param param 参数
     * @param func 待执行的方法
     * @param <T> 值类型
     * @param <P> 参数类型
     */
    public static <T, P> void isNotNullWithParam(T value, P param, Consumer<P> func) {
        ofNullWithParam(value, param, p -> {}, func);
    }

}
